package cn.iocoder.yudao.module.trade.aftersale.controller.app;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.business.basic.pojo.vo.UserSimpleVO;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.region.RegionUtils;
import cn.iocoder.yudao.framework.region.enums.RegionDataSet;
import cn.iocoder.yudao.module.api.member.user.MemberUserApi;
import cn.iocoder.yudao.module.api.shop.info.ShopInfoApi;
import cn.iocoder.yudao.module.api.shop.info.dto.ShopInfoDTO;
import cn.iocoder.yudao.module.trade.aftersale.convert.AfterSaleConvert;
import cn.iocoder.yudao.module.trade.aftersale.dal.dataobject.AfterSaleDO;
import cn.iocoder.yudao.module.trade.aftersale.service.AfterSaleService;
import cn.iocoder.yudao.module.trade.aftersale.service.ZXHXAfterSaleSyncService;
import cn.iocoder.yudao.module.trade.aftersale.vo.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.api.trade.ErrorCodeConstants.AFTER_SALE_ADDRESS_MISSING;
import static cn.iocoder.yudao.module.api.trade.ErrorCodeConstants.AFTER_SALE_NOT_FOUND;

@Tag(name = "用户 App - 售后订单")
@RestController
@RequestMapping("/trade/after-sale")
@Validated
@Slf4j
public class AppAfterSaleController {

    @Resource
    private AfterSaleService afterSaleService;
    @Resource
    private ZXHXAfterSaleSyncService zxhxAfterSaleSyncService;

    @Resource
    private ShopInfoApi shopInfoApi;
    @Resource
    private MemberUserApi memberUserApi;

    @GetMapping(value = "/page")
    @Operation(summary = "获得售后分页（买家）")
    public CommonResult<PageResult<AppAfterSaleRespVO>> getAfterSalePage(AppAfterSalePageReqVO pageParam) {
        PageResult<AfterSaleDO> page = afterSaleService.getAfterSalePage(getLoginUserId(), pageParam);
        List<AfterSaleDO> list = page.getList();
        if (CollUtil.isEmpty(list)) {
            return success(PageResult.empty());
        }
        Set<Long> shopIds = list.stream().map(AfterSaleDO::getShopId).collect(Collectors.toSet());
        Map<Long, ShopInfoDTO> shops = shopInfoApi.getShopInfoMap(shopIds);
        PageResult<AppAfterSaleRespVO> data = AfterSaleConvert.INSTANCE.convertPage02(page);
        data.getList().forEach(vo -> vo.setShop(shops.get(vo.getShopId())));
        return success(data);
    }

    @GetMapping(value = "/page-seller")
    @Operation(summary = "获得售后分页（卖家）")
    @PreAuthorize("@mm.isMerchant()")
    public CommonResult<PageResult<AppAfterSaleRespVO>> getSellerAfterSalePage(AppAfterSalePageReqVO pageParam) {
        Long shopId = getShopId();
        PageResult<AfterSaleDO> page = afterSaleService.getSellerAfterSalePage(shopId, pageParam);
        return success(AfterSaleConvert.INSTANCE.convertPage02(page));
    }

    @GetMapping(value = "/get")
    @Operation(summary = "获得售后详情（买家，单个产品）")
    @Parameter(name = "id", description = "售后编号", required = true, example = "1")
    public CommonResult<AppAfterSaleRespVO> getMyAfterSale(@RequestParam("id") Long id) {
        AfterSaleDO afterSale = afterSaleService.getAfterSale(getLoginUserId(), id);
        if (afterSale == null) {
            return error(AFTER_SALE_NOT_FOUND);
        }
        if (StrUtil.isNotBlank(afterSale.getSupplyRelatedNo())) {
            zxhxAfterSaleSyncService.syncAfterSaleInfoAsync(afterSale.getSupplyRelatedNo(), afterSale);
        }
        AppAfterSaleRespVO data = AfterSaleConvert.INSTANCE.convert(afterSale);
        ShopInfoDTO shop = shopInfoApi.getShopInfo(afterSale.getShopId());
        data.setSellerPhone(shop == null ? "" : shop.getContactMobile());
        return success(data);
    }

    @GetMapping(value = "/get-by-order")
    @Operation(summary = "获得售后详情（买家，整单）")
    @Parameter(name = "orderId", description = "订单编号", required = true, example = "1")
    public CommonResult<AppAfterSaleOrderVO> getMyAfterSaleByOrder(@RequestParam("orderId") Long orderId) {
        List<AfterSaleDO> afterSales = afterSaleService.getAfterSaleByOrderId(getLoginUserId(), orderId);
        if (CollUtil.isEmpty(afterSales)) {
            return error(AFTER_SALE_NOT_FOUND);
        }
        AppAfterSaleOrderVO data = AfterSaleConvert.INSTANCE.convert2(afterSales.get(0));
        data.setSkus(AfterSaleConvert.INSTANCE.convertList(afterSales));
        ShopInfoDTO shop = shopInfoApi.getShopInfo(afterSales.get(0).getShopId());
        for (AfterSaleDO afterSale : afterSales) {
            if (StrUtil.isNotBlank(afterSale.getSupplyRelatedNo())) {
                zxhxAfterSaleSyncService.syncAfterSaleInfoAsync(afterSale.getSupplyRelatedNo(), afterSale);
            }
            data.setSellerPhone(shop == null ? "" : shop.getContactMobile());
        }
        return success(data);
    }

    @GetMapping(value = "/get-seller")
    @Operation(summary = "获得售后详情（卖家，单个产品）")
    @Parameter(name = "id", description = "售后编号", required = true, example = "1")
    @PreAuthorize("@mm.isMerchant()")
    public CommonResult<AppAfterSaleRespVO> getSellerAfterSale(@RequestParam("id") Long id) {
        Long shopId = getShopId();
        AfterSaleDO afterSale = afterSaleService.getSellerAfterSale(shopId, id);
        if (afterSale == null) {
            return error(AFTER_SALE_NOT_FOUND);
        }
        if (StrUtil.isNotBlank(afterSale.getSupplyRelatedNo())) {
            zxhxAfterSaleSyncService.syncAfterSaleInfoAsync(afterSale.getSupplyRelatedNo(), afterSale);
        }
        AppAfterSaleRespVO data = AfterSaleConvert.INSTANCE.convert(afterSale);
        UserSimpleVO user = memberUserApi.getUser(afterSale.getUserId());
        data.setBuyerPhone(user == null ? "" : user.getMobile());
        return success(data);
    }

    @GetMapping(value = "/get-seller-by-order")
    @Operation(summary = "获得售后详情（卖家，整单）")
    @Parameter(name = "orderId", description = "订单编号", required = true, example = "1")
    @PreAuthorize("@mm.isMerchant()")
    public CommonResult<AppAfterSaleOrderVO> getSellerAfterSaleByOrder(@RequestParam("orderId") Long orderId) {
        Long shopId = getShopId();
        List<AfterSaleDO> list = afterSaleService.getSellerAfterSaleByOrderId(shopId, orderId);
        if (CollUtil.isEmpty(list)) {
            return error(AFTER_SALE_NOT_FOUND);
        }
        AppAfterSaleOrderVO data = AfterSaleConvert.INSTANCE.convert2(list.get(0));
        data.setSkus(AfterSaleConvert.INSTANCE.convertList(list));
        UserSimpleVO user = memberUserApi.getUser(list.get(0).getUserId());
        for (AfterSaleDO afterSale : list) {
            if (StrUtil.isNotBlank(afterSale.getSupplyRelatedNo())) {
                zxhxAfterSaleSyncService.syncAfterSaleInfoAsync(afterSale.getSupplyRelatedNo(), afterSale);
            }
            data.setBuyerPhone(user == null ? "" : user.getMobile());
        }
        return success(data);
    }

    @GetMapping(value = "/get-delivery-address")
    @Operation(summary = "获得卖家的寄货地址（买家，单个产品）")
    @Parameter(name = "id", description = "售后编号", required = true, example = "1")
    public CommonResult<AppAfterSaleDeliveryAddressRespVO> getAfterSaleDeliveryAddress(@RequestParam("id") Long id) {
        AfterSaleDO afterSale = afterSaleService.getAfterSale(id);
        return toDeliveryAddressResult(afterSale);
    }

    @GetMapping(value = "/get-delivery-address-by-order")
    @Operation(summary = "获得卖家的寄货地址（买家，整单）")
    @Parameter(name = "orderId", description = "订单编号", required = true, example = "1")
    public CommonResult<AppAfterSaleDeliveryAddressRespVO> getAfterSaleDeliveryAddressByOrder(@RequestParam("orderId") Long orderId) {
        List<AfterSaleDO> list = afterSaleService.getAfterSaleByOrderId(getLoginUserId(), orderId);
        if (CollUtil.isEmpty(list)) {
            return error(AFTER_SALE_NOT_FOUND);
        }
        AfterSaleDO afterSale = list.get(0);
        return toDeliveryAddressResult(afterSale);
    }

    private CommonResult<AppAfterSaleDeliveryAddressRespVO> toDeliveryAddressResult(AfterSaleDO afterSale) {
        AppAfterSaleDeliveryAddressRespVO respVO = new AppAfterSaleDeliveryAddressRespVO();
        respVO.setName(afterSale.getDeliveryName());
        respVO.setMobile(afterSale.getDeliveryMobile());
        respVO.setProvinceCode(RegionUtils.convertRegionIdToCode(afterSale.getDeliveryProvinceId()));
        respVO.setCityCode(RegionUtils.convertRegionIdToCode(afterSale.getDeliveryCityId()));
        respVO.setCountyCode(RegionUtils.convertRegionIdToCode(afterSale.getDeliveryAreaId()));
        respVO.setDetailAddress(afterSale.getDeliveryDetailAddress());
        RegionUtils.autoAssignCounty(RegionDataSet.ONLY_LATEST, respVO.getCountyCode(), respVO);
        return success(respVO);
    }

    @PostMapping(value = "/create")
    @Operation(summary = "申请售后（买家）")
    public CommonResult<Long> createAfterSale(@RequestBody AppAfterSaleCreateReqVO createReqVO) {
        return success(afterSaleService.createAfterSale(getLoginUserId(), createReqVO));
    }

    @PostMapping(value = "/delivery")
    @Operation(summary = "退回货物（买家）")
    public CommonResult<Boolean> deliveryAfterSale(@RequestBody AppAfterSaleDeliveryReqVO deliveryReqVO) {
        afterSaleService.deliveryAfterSale(getLoginUserId(), deliveryReqVO);
        return success(true);
    }

    @PostMapping(value = "/cancel")
    @Operation(summary = "取消售后（买家，单个产品）")
    @Parameter(name = "id", description = "售后编号", required = true, example = "1")
    public CommonResult<Boolean> cancelAfterSale(@RequestParam("id") Long id) {
        afterSaleService.cancelAfterSale(getLoginUserId(), id);
        return success(true);
    }

    @PostMapping(value = "/cancel-by-order")
    @Operation(summary = "取消售后（买家，整单）")
    @Parameter(name = "orderId", description = "订单编号", required = true, example = "1")
    public CommonResult<Boolean> cancelAfterSaleByOrder(@RequestParam("orderId") Long orderId) {
        afterSaleService.cancelAfterSaleByOrder(getLoginUserId(), orderId);
        return success(true);
    }

    @PostMapping(value = "/agree")
    @Operation(summary = "同意售后（无寄送地址，卖家，单个产品）")
    @Parameter(name = "id", description = "售后编号", required = true, example = "1")
    @PreAuthorize("@mm.isMerchant()")
    public CommonResult<Boolean> agreeAfterSale(@RequestParam("id") Long id) {
        AfterSaleAgreeReqVO reqVO = new AfterSaleAgreeReqVO();
        reqVO.setId(id);
        afterSaleService.agreeAfterSale(getShopId(), reqVO);
        return success(true);
    }

    @PostMapping(value = "/agree-by-order")
    @Operation(summary = "同意售后（仅退款，无寄送地址，卖家，整单）")
    @Parameter(name = "orderId", description = "订单编号", required = true, example = "1")
    @PreAuthorize("@mm.isMerchant()")
    public CommonResult<Boolean> agreeAfterSaleByOrder(@RequestParam("orderId") Long orderId) {
        AfterSaleAgreeReqVO reqVO = new AfterSaleAgreeReqVO();
        reqVO.setOrderId(orderId);
        afterSaleService.agreeAfterSale(getShopId(), reqVO);
        return success(true);
    }

    @PostMapping(value = "/agree-address")
    @Operation(summary = "同意售后（退货退款，有寄送地址，卖家）")
    @PreAuthorize("@mm.isMerchant()")
    public CommonResult<Boolean> agreeAfterSaleAddress(@Valid @RequestBody AfterSaleAgreeReqVO reqVO) {
        if (reqVO.getDeliveryAreaId() == null || reqVO.getDeliveryAreaId() == 0
            || StrUtil.isBlank(reqVO.getDeliveryDetailAddress())) {
            return error(AFTER_SALE_ADDRESS_MISSING);
        }
        afterSaleService.agreeAfterSale(getShopId(), reqVO);
        return success(true);
    }

    @PostMapping(value = "/disagree")
    @Operation(summary = "拒绝售后（卖家）")
    @PreAuthorize("@mm.isMerchant()")
    public CommonResult<Boolean> disagreeAfterSale(@Valid @RequestBody AfterSaleDisagreeReqVO reqVO) {
        afterSaleService.disagreeAfterSale(getShopId(), reqVO);
        return success(true);
    }

    @PostMapping(value = "/receive")
    @Operation(summary = "确认收货（卖家，单个产品）")
    @Parameter(name = "id", description = "售后编号", required = true, example = "1")
    @PreAuthorize("@mm.isMerchant()")
    public CommonResult<Boolean> receiveAfterSale(@RequestParam("id") Long id) {
        afterSaleService.receiveAfterSale(getShopId(), id);
        return success(true);
    }

    @PostMapping(value = "/receive-by-order")
    @Operation(summary = "确认收货（卖家，整单）")
    @Parameter(name = "orderId", description = "订单编号", required = true, example = "1")
    @PreAuthorize("@mm.isMerchant()")
    public CommonResult<Boolean> receiveAfterSaleByOrder(@RequestParam("orderId") Long orderId) {
        afterSaleService.receiveAfterSaleByOrder(getShopId(), orderId);
        return success(true);
    }

    @PostMapping(value = "/refuse")
    @Operation(summary = "拒绝收货（卖家）")
    @PreAuthorize("@mm.isMerchant()")
    public CommonResult<Boolean> refuseAfterSale(AfterSaleRefuseReqVO refuseReqVO) {
        afterSaleService.refuseAfterSale(getShopId(), refuseReqVO);
        return success(true);
    }

    private Long getShopId() {
        return shopInfoApi.getShopIdByMemberUserId(getLoginUserId());
    }

}
